// src/utils/websocket/index.js
import type { WsMessage, WsOptions } from './type'; // TypeScript类型

class WebSocketService {
    private socket: WebSocket | null = null;
    private url: string = '';
    private token: string = '';
    private isConnected: boolean = false;
    private reconnectTimer: NodeJS.Timeout | null = null;
    private reconnectDelay: number = 3000; // 重连间隔（ms）
    private messageHandlers: Map<string, (data: any) => void> = new Map(); // 消息处理器

    // 初始化配置
    init(options: WsOptions) {
        this.url = options.url;
        this.token = options.token;
        this.connect();
    }

    // 建立连接
    private connect() {
        if (this.socket) this.socket.close();

        // 构造连接地址（通过Sec-WebSocket-Protocol传递token）
        const socket = new WebSocket(this.url, [`token=${this.token}`]);
        this.socket = socket;

        // 连接成功
        socket.onopen = () => {
            this.isConnected = true;
            this.clearReconnectTimer();
            this.emit('connect', '连接成功');
        };

        // 接收消息
        socket.onmessage = (event) => {
            const message: WsMessage = JSON.parse(event.data);
            // 根据消息类型分发到对应处理器
            const handler = this.messageHandlers.get(message.type) || this.messageHandlers.get('*');
            if (handler) handler(message);
        };

        // 错误处理
        socket.onerror = (error) => {
            this.emit('error', error);
        };

        // 连接关闭（处理重连）
        socket.onclose = (event) => {
            this.isConnected = false;
            this.emit('close', event);
            // 非正常关闭则重连（排除主动关闭）
            if (event.code !== 1000) {
                this.reconnect();
            }
        };
    }

    // 重连逻辑
    private reconnect() {
        this.clearReconnectTimer();
        this.reconnectTimer = setTimeout(() => {
            this.emit('reconnect', `正在重连（${this.reconnectDelay}ms后）`);
            this.connect();
        }, this.reconnectDelay);
    }

    // 发送消息
    sendMessage(data: Partial<WsMessage>) {
        if (!this.isConnected || !this.socket) {
            this.emit('error', new Error('连接未建立，无法发送消息'));
            return false;
        }
        try {
            // 补全消息默认字段（如类型、时间戳）
            const message: WsMessage = {
                type: data.type || 'chat',
                content: data.content,
                timestamp: Date.now(),
                ...data,
            };
            this.socket.send(JSON.stringify(message));
            return true;
        } catch (error) {
            this.emit('error', error);
            return false;
        }
    }

    // 注册消息处理器（组件可通过此方法监听特定类型消息）
    onMessage(type: string, handler: (data: any) => void) {
        this.messageHandlers.set(type, handler);
    }

    // 移除消息处理器
    offMessage(type: string) {
        this.messageHandlers.delete(type);
    }

    // 主动关闭连接
    close() {
        if (this.socket) {
            this.socket.close(1000, '主动关闭');
            this.socket = null;
        }
        this.clearReconnectTimer();
    }

    // 辅助：触发事件（供外部监听）
    private emit(event: string, data: any) {
        // 可通过自定义事件或回调函数暴露给外部
        // 示例：用window.dispatchEvent触发全局事件，或在composables中监听
        window.dispatchEvent(new CustomEvent(`ws:${event}`, { detail: data }));
    }

    // 辅助：清除重连定时器
    private clearReconnectTimer() {
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
            this.reconnectTimer = null;
        }
    }
}

// 导出单例实例
export const wsService = new WebSocketService();
